//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/python.h>

#include <buola/app/ceventloop.h>
#include <buola/algorithm/comparison.h>

#include <buola/python/cpythonhelp.h>
#include <buola/util/chelpwindow.h>
#include <buola/python.h>

namespace buola { namespace python {

const std::string CPythonHelp::mPythonTypeName("buolahelp");

CPythonHelp::CPythonHelp()
{
    mPyDoc=python::import_module("pydoc");
    YClass lClass(mPyDoc.GetAttribute("HTMLDoc"));
    mHTMLDoc=lClass.NewInstance();
    mWindow=nullptr;
}

CPythonHelp::~CPythonHelp()
{
}

YObject CPythonHelp::Help(const YObject &pArgs)
{
    YObject lArg;

    if(!parse_args(pArgs,"O",lArg))
    {
        return YObject();
    }

    lock_guard<recursive_mutex> lLock(get_main_event_loop().GetMutex());

/*  if(!mWindow)
    {
        mWindow=CHelpWindow::GetHelpWindow();
        mWindow->sURIRequested.Connect(&CPythonHelp::OnURIRequested,this,_1);
    }
    mWindow->Show();
    mWindow->Activate();
    std::wstring lURI(L"http://pydoc/pythondoc.html");
    mWindow->OpenDocument(lURI,GetHelpForObject(lArg));
*/
    return Py_None;
}

std::wstring CPythonHelp::GetHelpForObject(const YObject &pObject)
{
    YObject lHTMLCode;
    YObject lObjType=pObject.GetType();
    std::string lTypeName(((PyTypeObject*)(PyObject*)lObjType)->tp_name);

    if(pObject.IsModule())
    {
        lHTMLCode=mHTMLDoc.CallMethod("docmodule",pObject);
    }
    else if(pObject.IsType()||lTypeName=="classobj")
    {
        lHTMLCode=mHTMLDoc.CallMethod("docclass",pObject);
    }
    else if(pObject.IsCallable())
    {
        lHTMLCode=mHTMLDoc.CallMethod("docroutine",pObject);
    }
    else if(pObject.IsInstance())
    {
        lHTMLCode=mHTMLDoc.CallMethod("docclass",
                            pObject.GetAttribute("__class__"));
    }
    else
    {
        lHTMLCode=mHTMLDoc.CallMethod("docclass",lObjType);
    }

    YObject lHTMLPage=mHTMLDoc.CallMethod("page",YObject("doc"),lHTMLCode);
    return lHTMLPage.ToWString();
}

std::wstring CPythonHelp::GetHelpForName(const std::wstring &pName)
{
    python::CLock lLock;

    std::string lName=utf8(pName);
    YModule lModule(lName);

    return GetHelpForObject(lModule);
}

void CPythonHelp::AddMethods()
{
    ADD_PYTHON_METHOD("help",Help,
                        L"displays help for any object");
}

bool CPythonHelp::OnURIRequested(const std::wstring &pURI)
{
    if(starts_with(pURI,L"http://pydoc/"))
    {
        std::wstring lRest=pURI.substr(13);
        int lPoint=lRest.find('.');
        std::wstring lName=lRest.substr(0,lPoint);

//      mWindow->OpenDocument(pURI,GetHelpForName(lName));

        return false;
    }

    return true;
}

/*namespace python*/ } /*namespace buola*/ }
